#include "pinctrl.h"
#include "pwm.h"
#include "osal_debug.h"
#include "cmsis_os2.h"
#include "app_init.h"
#include "tcxo.h"
#include "rgb.h"
#include <stdbool.h>

static rgb_drv_t rgb_drv;

static void pwm_channel_init(void)
{
    /* 初始化所有通道为关闭状态 */
    rgb_drv.pwm_cfg_r = (pwm_config_t){0,PWM_PERIOD, 0, 0, true};
    rgb_drv.pwm_cfg_g = (pwm_config_t){0,PWM_PERIOD, 0, 0, true};
    rgb_drv.pwm_cfg_b = (pwm_config_t){0,PWM_PERIOD, 0, 0, true};

    /* 配置引脚模式 */
    uapi_pin_set_mode(CONFIG_GPIO_R, PWM_MODE);
    uapi_pin_set_mode(CONFIG_GPIO_G, PWM_MODE);
    uapi_pin_set_mode(CONFIG_GPIO_B, PWM_MODE);

    /* 初始化PWM模块 */
    uapi_pwm_deinit();
    uapi_pwm_init();

    /* 打开PWM通道 */
    uapi_pwm_open(CONFIG_GPIO_R_CHANNEL, &rgb_drv.pwm_cfg_r);
    uapi_pwm_open(CONFIG_GPIO_G_CHANNEL, &rgb_drv.pwm_cfg_g);
    uapi_pwm_open(CONFIG_GPIO_B_CHANNEL, &rgb_drv.pwm_cfg_b);

    // /* 启动所有通道 */
    // uapi_pwm_start(CONFIG_GPIO_R_CHANNEL);
    // uapi_pwm_start(CONFIG_GPIO_G_CHANNEL);
    // uapi_pwm_start(CONFIG_GPIO_B_CHANNEL);
    /* 将三个通道加入组中再启动 */
    uint8_t channel_ids[3] = {CONFIG_GPIO_R_CHANNEL, CONFIG_GPIO_G_CHANNEL, CONFIG_GPIO_B_CHANNEL};
    uapi_pwm_set_group(RGB_GROUP_ID, channel_ids, 3);
    uapi_pwm_start_group(RGB_GROUP_ID);

    uapi_tcxo_delay_ms(TEST_TCXO_DELAY_1000MS);
}

void RGB_Init(void)
{
    pwm_channel_init();
}

void RGB_Deinit(void)
{
    // uapi_pwm_stop(CONFIG_GPIO_R_CHANNEL);
    // uapi_pwm_stop(CONFIG_GPIO_G_CHANNEL);
    // uapi_pwm_stop(CONFIG_GPIO_B_CHANNEL);
    
    // uapi_pwm_close(CONFIG_GPIO_R_CHANNEL);
    // uapi_pwm_close(CONFIG_GPIO_G_CHANNEL);
    // uapi_pwm_close(CONFIG_GPIO_B_CHANNEL);
    uapi_pwm_close(RGB_GROUP_ID);
    uapi_tcxo_delay_ms((uint32_t)TEST_TCXO_DELAY_1000MS);
    uapi_pwm_deinit();
}

void RGB_SetDutyCycle(uint8_t channel, float duty_cycle)
{

    /* 参数有效性检查 */
    duty_cycle = (duty_cycle < 0.0f) ? 0.0f : 
                (duty_cycle > 1.0f) ? 1.0f : duty_cycle;

    uint32_t low = (uint32_t)(duty_cycle * PWM_PERIOD);
    uint32_t high = PWM_PERIOD - low;

    switch(channel) {
        case CONFIG_GPIO_R_CHANNEL:
            rgb_drv.pwm_cfg_r.high_time = high;
            rgb_drv.pwm_cfg_r.low_time = low;
            uapi_pwm_open(CONFIG_GPIO_R_CHANNEL, &rgb_drv.pwm_cfg_r);
            break;
            
        case CONFIG_GPIO_G_CHANNEL:
            rgb_drv.pwm_cfg_g.high_time = high;
            rgb_drv.pwm_cfg_g.low_time = low;
            uapi_pwm_open(CONFIG_GPIO_G_CHANNEL, &rgb_drv.pwm_cfg_g);
            break;
            
        case CONFIG_GPIO_B_CHANNEL:
            rgb_drv.pwm_cfg_b.high_time = high;
            rgb_drv.pwm_cfg_b.low_time = low;
            uapi_pwm_open(CONFIG_GPIO_B_CHANNEL, &rgb_drv.pwm_cfg_b);
            break;
            
        default:
            osal_printk("Invalid RGB channel\r\n");
            break;
    }

    
}

void RGB_SetColor(uint8_t red, uint8_t green, uint8_t blue)
{
    uapi_pwm_close(RGB_GROUP_ID);

    RGB_SetDutyCycle(CONFIG_GPIO_R_CHANNEL, red/255.0f);
    RGB_SetDutyCycle(CONFIG_GPIO_G_CHANNEL, green/255.0f);
    RGB_SetDutyCycle(CONFIG_GPIO_B_CHANNEL, blue/255.0f);
    uapi_pwm_start_group(RGB_GROUP_ID);
}